/*
 * @Descripttion: 
 * @version: 
 * @Author: lily
 * @Date: 2021-04-03 14:39:20
 * @LastEditors: lily
 * @LastEditTime: 2021-04-03 15:36:26
 */
/**
 * @param {string} s
 * @return {boolean}
 */
//  思路：
//  根据新添加的数字跳转不同的状态 遍历完成后判断是否是合法状态
//  复杂度：O(n) O(1)

var isNumber = function (s) {
    var states = [
        // 状态0  开头空格  加空格=>0   加+/-=>1   加数字=>2   加'.'=>4
        new Map([[' ', 0], ['s', 1], ['d', 2], ['.', 4]]),
        // 状态1  符号      加数字=>2   加'.'=>4
        new Map([['d', 2], ['.', 4]]),
        // 状态2  .前数字   加数字=>2   加'.'=>3   加'e'=>5   加空格=>8
        new Map([['d', 2], ['.', 3], ['e', 5], [' ', 8]]),
        // 状态3  .后数字   加数字=>3   加'e'=>5   加空格=>8
        new Map([['d', 3], ['e', 5], [' ', 8]]),
        // 状态4 .后        加数字=>3
        new Map([['d', 3]]),
        // 状态5 e后        加+/-=>6    加数字=>7
        new Map([['s', 6], ['d', 7]]),
        // 状态6 e后符号后  加数字=>7
        new Map([['d', 7]]),
        // 状态7 e后数字    加数字=>7   加空格=>8
        new Map([['d', 7], [' ', 8]]),
        // 状态8 末尾空格   加空格=>8
        new Map([[' ', 8]])
    ]
    var p = 0, t;
    for (c of s) {
        // 数字
        if ('0' <= c && c <= '9') t = 'd';
        // +/- 符号
        else if (c == '+' || c == '-') t = 's';
        // e/E
        else if (c == 'e' || c == 'E') t = 'e';
        // . 小数点
        else if (c == '.' || c == ' ') t = c;
        // 其他
        else t = '?';
        // 如果不属于第一个状态 不是数字  has()用来检测是否存在指定的key
        if (!states[p].has(t)) return false;
        // 根据添加的结果跳转状态  get() 根据key获得value
        p = states[p].get(t);
    }
    return p == 2 || p == 3 || p == 7 || p == 8;

};

isNumber('123.4')